// test1.cpp - Copyright (C) 2013 Willow Schlanger. All rights reserved. See univm_license.txt.
// --------------------------------------------------------------------------------------------
// sudo apt-get install libboost-dev
// sudo apt-get install libboost-thread-dev
// sudo apt-get install libboost-system-dev
// clang++ -O2 -o test1.out test1.cpp -lboost_system -lboost_thread-mt -I../../include -Wall
// ============================================================================================

#include <infrared/infrared.h>
#include <infrared/fastvec.h>

//------------------------------------------------------------------------------------------------------------------------------------------------//

using namespace isb;

int active = 0;

struct foo
{
	int x;

	foo() : x(0) { ++active; }
	foo(int aT) : x(aT) { ++active; }
	foo(const foo &src) : x(src.x) { ++active; }
	~foo() { --active; }
	//>>~foo() { std::cout << "~" << x << std::endl; x = 12345; }
};

int main(int arc, char *argv[])
{
	{
		ref_t<int> x1 = ref_t<int>::allocate(true);   // use fast allocator
		ref_t<int> x2 = ref_t<int>::allocate(false);  // do not use fast allocator

		*x1 = 1;
		*x2 = 2;
	
		ref_t<int> x3 = ref_t<int>::allocate_array(4, 555);
	
		for(usize_t i = 0; i < x3.size(); ++i)
		{
			std::cout << x3[i] << std::endl;
		}
	
		std::cout << "The size of x2 is: " << x2.size() << std::endl;
		std::cout << "\n---" << std::endl;
	}

	{	
		fastvec_t<foo> v;
		for(int i = 0; i < 20; ++i)
		{
			std::cout << 5 + 10 * i << " " << std::flush;
			v.push_back(foo(5 + 10 * i));
		}
	
		std::cout << "\n" << v.front().x << " " << v.back().x << std::endl;

		for(int i = 10; i < 20; ++i)
			v.pop_back();

		std::cout << v.front().x << " " << v.back().x << std::endl;
	
		if(!v.empty())
		{
			v.push_back(foo(123));
			v.pop_back();
			v.front().x = 2;
			v.back() = *--v.end();
			v[0].x = 5;
		}
	
		for(fastvec_t<foo>::iterator i = v.begin(); i != v.end(); ++i)
		{
			std::cout << i->x << " " << std::flush;
		}
		std::cout << std::endl;

		const fastvec_t<foo> &cv = v;
		for(fastvec_t<foo>::const_iterator i = cv.end(); ;)
		{
			if(i == cv.begin())
				break;
			--i;
			std::cout << i->x << " " << std::flush;
		}
		std::cout << std::endl;
	
		++cv.begin();  --cv.end();  cv.begin()++;  cv.begin() += 2;  cv.end() -= 3; cv.end()--;  cv.end() - cv.begin();  cv.end() + 0;  cv.begin() - 0;
		++v.begin();  --v.end();  v.begin()++;  v.begin() += 2;  v.end() -= 3; v.end()--;  v.end() - v.begin();  v.end() + 0;  v.begin() - 0;
		cv.end() < cv.begin();  v.end() < v.begin();  (void)(v.begin() == v.end());  (void)(cv.begin() == cv.end());

		v.clear();
		usize_t count = 0;
		v.resize(32, foo(123));
		for(fastvec_t<foo>::iterator i = v.begin(); i != v.end(); ++i)
		{
			std::cout << i->x << " " << std::flush;
			++count;
		}
		std::cout << std::endl;
		std::cout << "Got " << count << " vs. " << v.size() << std::endl;

		fastvec_t<foo> v3(v.begin(), v.end());
		fastvec_t<foo> v2 = v3;
		v2 = v3;
		v.resize(4);
		count = 0;
		for(fastvec_t<foo>::iterator i = v.begin(); i != v.end(); ++i)
		{
			std::cout << i->x << " " << std::flush;
			++count;
		}
		std::cout << std::endl;
		std::cout << "Got " << count << " vs. " << v.size() << std::endl;

		count = 0;
		for(fastvec_t<foo>::iterator i = v2.begin(); i != v2.end(); ++i)
		{
			std::cout << i->x << " " << std::flush;
			++count;
		}
		std::cout << std::endl;
		std::cout << "Got " << count << " vs. " << v2.size() << std::endl;

		//>v2.begin().invalidate();
		//>cv.begin().invalidate();

		v = v2;
		std::cout << v2.size() << std::endl;
		v.clear();
		std::cout << v2.size() << std::endl;
		count = 0;
		for(fastvec_t<foo>::iterator i = v.begin(); i != v.end(); ++i)
		{
			std::cout << i->x << " " << std::flush;
			++count;
		}
		std::cout << "(should be empty)" << std::endl;
		std::cout << "Got " << count << " vs. " << v.size() << std::endl;
	
		v2.begin()[0];
		cv.begin()[0];
	
		fastvec_t<int> vec1;
		std::cout << sizeof(vec1) << std::endl;
	}
	std::cout << "\nstill active (should be 0): " << active << std::endl;

	return 0;
}
